package com.sikaryofficial.workbench.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.sikaryofficial.common.core.domain.R;
import com.sikaryofficial.common.core.exception.ServiceException;
import com.sikaryofficial.common.core.web.domain.PageResult;
import com.sikaryofficial.workbench.domain.dto.req.goods.CreateOrUpdateGoodsReq;
import com.sikaryofficial.workbench.domain.dto.req.goods.GoodsManageListReq;
import com.sikaryofficial.workbench.domain.dto.req.goods.UpdateGoodsStatusReq;
import com.sikaryofficial.workbench.domain.dto.resp.goods.GoodsManageDetailDTO;
import com.sikaryofficial.workbench.domain.dto.resp.goods.GoodsManageListDTO;
import com.sikaryofficial.workbench.domain.entity.GoodsOperateLog;
import com.sikaryofficial.workbench.domain.eo.GoodsEO;
import com.sikaryofficial.workbench.manager.GoodsManager;
import com.sikaryofficial.workbench.utils.TemplateLoader;
import com.sikaryofficial.workbench.utils.excel.listener.ImportListener;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 运营商品管理控制器
 */
@RestController
@RequestMapping("/goods/manage")
@Api(tags = "运营-商品管理模块")
@Slf4j
public class GoodsManagerController {
    @Autowired
    private GoodsManager goodsManager;

    @Autowired
    private TemplateLoader templateLoader;

    @PostMapping("/listPage")
    @ApiOperation("商品分页列表")
    public PageResult<GoodsManageListDTO> goodsManagePage(@RequestBody GoodsManageListReq req) {
        return goodsManager.goodsManagePage(req);
    }

    @PostMapping("/saveGoods")
    @ApiOperation("创建商品")
    public R<Long> saveGoods(@RequestBody @Validated CreateOrUpdateGoodsReq req) {
        return R.ok(goodsManager.saveGoods(req));
    }

    @GetMapping("/detail/{goodsId}")
    @ApiOperation("商品详情")
    public R<GoodsManageDetailDTO> detail(@PathVariable Long goodsId) {
        return R.ok(goodsManager.goodsManageDetail(goodsId));
    }

    @GetMapping("/logInfo/{goodsId}")
    @ApiOperation("商品操作日志")
    public R<List<GoodsOperateLog>> logInfo(@PathVariable Long goodsId) {
        return R.ok(goodsManager.logInfo(goodsId));
    }

    @PostMapping("/updateGoods")
    @ApiOperation("更新商品")
    public R<Long> updateGoods(@RequestBody @Validated CreateOrUpdateGoodsReq req) {
        return R.ok(goodsManager.updateGoods(req));
    }

    @PostMapping("/delete")
    @ApiOperation("删除商品")
    public R<Boolean> deleteGoods(@RequestBody List<Long> goodsIds) {
        return R.ok(goodsManager.deleteGoods(goodsIds));
    }

    @PostMapping("/updateListingStatus")
    @ApiOperation("商品上下架")
    public R<Boolean> updateListingStatus(@RequestBody UpdateGoodsStatusReq req) {
        return R.ok(goodsManager.updateListingStatus(req));
    }

    @PostMapping("/listRecommendGoods")
    @ApiOperation("推荐商品列表展示")
    public R<List<GoodsManageListDTO>> listRecommendGoods() {
        return R.ok(goodsManager.listRecommendGoods());
    }

    @PostMapping("/updateRecommendGoods")
    @ApiOperation("设置推荐商品")
    public R<Boolean> updateRecommendGoods(@RequestBody List<Long> goodsIds) {
        return R.ok(goodsManager.updateRecommendGoods(goodsIds));
    }

    @PostMapping("/downloadImportTemplate")
    @ApiOperation("导入模版下载")
    public void downloadImportTemplate(HttpServletResponse response) {
        // 外置本地文件夹方式管理
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "商品导入模版";
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            templateLoader.loadAndWrite("goods_import.xlsx", response.getOutputStream());
        } catch (Exception e) {
            log.error("goodsExport", e);
            throw new ServiceException("goods export error.");
        }
    }

    @PostMapping("/batchImport")
    @ApiOperation("商品导入")
    public R<Boolean> batchImport(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream()) {
            ImportListener<GoodsEO> ImportListener = new ImportListener<>();
            EasyExcelFactory.read(inputStream)
                    .head(GoodsEO.class)
                    .registerReadListener(ImportListener)
                    .headRowNumber(2)
                    .sheet()
                    .doRead();
            return R.ok(goodsManager.saveGoodsEO(ImportListener.getList()));
        }
    }

    @PostMapping("/batchExport")
    @ApiOperation("商品导出")
    public void batchExport(HttpServletResponse response, @RequestBody List<Long> goodsIds) {
        if (goodsIds == null || goodsIds.isEmpty()) {
            throw new ServiceException("商品ID不能为空");
        }
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "商品导出" + LocalDateTimeUtil.format(LocalDateTime.now(), DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_FORMAT.getPattern()));
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcelFactory.write(response.getOutputStream())
                    .withTemplate(templateLoader.load("goods_export.xlsx"))
//                    .head(GoodsEO.class)
                    .sheet()
                    .doWrite(goodsManager.listGoodsEO(goodsIds));
        } catch (Exception e) {
            log.error("goodsExport", e);
            throw new ServiceException("goods export error.");
        }
    }
}
